package com.xbongbong.paas.script.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.script.pojo.dto.ProductDTO;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.service.WaitSeriesService;
import com.xbongbong.sys.domain.entity.CoverRoleEntity;
import com.xbongbong.sys.domain.entity.RoleEntity;
import com.xbongbong.sys.model.CompanyModel;
import com.xbongbong.sys.model.CoverRoleModel;
import com.xbongbong.sys.model.RoleModel;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;


/**
 * @Author: wujian
 * @Description: 归档权限
 * @Date: 下午3:29 2022/7/28
 * @Param:
 * @return:
 **/
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX + "/script/archive")
public class ArchivePermissionController {
    private static final Logger LOG = LoggerFactory.getLogger(ArchivePermissionController.class);

    @Resource
    private CompanyModel companyModel;
    @Resource
    private RoleModel roleModel;
    @Resource
    private CoverRoleModel coverRoleModel;


    /**
     *  有编辑权限的 默认添加归档权限
     *
     * @param productDTO
     * @param br
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/generatePermissions", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String generatePermissions(@RequestBody @Valid ProductDTO productDTO, BindingResult br) throws Exception {
        LOG.warn("---------------- 开始处理待系列老公司权限 -------------------");
        long start = DateTimeUtil.getInt();
        // 成功数
        Integer successNum = 0;
        // 不更新公司数
        Integer notUpdateNum = 0;
        // 如果没传公司ID就取所有公司
        List<String> corpidList = CollectionUtils.isNotEmpty(productDTO.getCorpidList()) ? productDTO.getCorpidList() : companyModel.getCorpidList();
        int i = 1;
        //更新失败公司ID集合
        Set<String> errorCorpidList = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("del",0);
        param.put("columns","id, permissions");
        for (String corpid : corpidList) {
            int x = corpidList.size() - i;
            LOG.info("-----------------------------当前是第" + i + "家公司,还有" + x + "家是公司需要刷--------------------------");
            i++;
            try {
                //获取公司全部角色
                param.put("corpid",corpid);
                //自定义权限
                List<RoleEntity> roleEntityList = roleModel.findAllRoleByCorpid(param);
                //系统权限
                List<CoverRoleEntity> coverRoleEntityList = coverRoleModel.findEntitys(param);
                List<RoleEntity> updateRoleEntity = new ArrayList<>();
                roleEntityList.forEach(roleEnt -> {
                    String permissions = setRolePermissions(roleEnt.getPermissions());
                    if (!Objects.equals(permissions, roleEnt.getPermissions())){
                        RoleEntity roleEntity = new RoleEntity();
                        roleEntity.setId(roleEnt.getId());
                        roleEntity.setPermissions(permissions);
                        updateRoleEntity.add(roleEntity);
                    }
                });
                List<CoverRoleEntity> updateCoverRoleEntity = new ArrayList<>();
                coverRoleEntityList.forEach(coverRoleEnt -> {
                    String permissions = setRolePermissions(coverRoleEnt.getPermissions());
                    if (!Objects.equals(permissions, coverRoleEnt.getPermissions())){
                        CoverRoleEntity coverRoleEntity = new CoverRoleEntity();
                        coverRoleEntity.setId(coverRoleEnt.getId());
                        coverRoleEntity.setPermissions(permissions);
                        updateCoverRoleEntity.add(coverRoleEntity);
                    }
                });
                if (CollectionsUtil.isNotEmpty(updateRoleEntity)){
                    roleModel.updateBatchPermissions(updateRoleEntity, corpid);
                }
                if (CollectionsUtil.isNotEmpty(updateCoverRoleEntity)){
                    coverRoleModel.updateBatchPermissions(updateCoverRoleEntity, corpid);
                }
                if (updateRoleEntity.isEmpty() && updateCoverRoleEntity.isEmpty()){
                    notUpdateNum++;
                }else {
                    successNum++;
                }
            } catch (Exception e) {
                LOG.error("公司编号为:" + corpid + "更新失败,失败理由是", e);
                errorCorpidList.add(corpid);
            }
        }
        LOG.error("更新失败公司ID集合" + errorCorpidList.toString());
        LOG.warn("不更新公司数为:" + notUpdateNum);
        LOG.warn("consume:" + (DateTimeUtil.getInt() - start));
        LOG.warn("更新自定义权限表中数据成功,本次共更新了[{}]家公司数据", successNum);
        JSONObject object = new JSONObject();
        object.put("success", "成功");
        return object.toJSONString();
    }

    /**
     * 添加归档权限
     * @param permissions
     * @return
     */
    public String setRolePermissions(String permissions){
        StringBuilder stringBuilder = new StringBuilder(permissions);
        List<String> permissionsId = Arrays.asList(permissions.split("\\|"));
        // 如果有合同的编辑权限 则加上合同的归档权限
        if (permissionsId.contains("43") && !permissionsId.contains("1322")){
            permissions = stringBuilder.append("1322|").toString();
        }
        // 如果有机会的编辑权限 则加上机会的归档权限
        if (permissionsId.contains("39") && !permissionsId.contains("1321")){
            permissions = stringBuilder.append("1321|").toString();
        }
        // 如果有客户的编辑权限 则加上客户的归档权限
        if (permissionsId.contains("45") && !permissionsId.contains("1320")){
            permissions = stringBuilder.append("1320|").toString();
        }
        // 如果有线索的编辑权限 则加上线索的归档权限
        if (permissionsId.contains("646") && !permissionsId.contains("1323")){
            permissions = stringBuilder.append("1323|").toString();
        }
        return permissions;
    }


    /**
     * 上线失败回滚方案
     * @param productDTO
     * @param br
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/robackPermissions", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String robackPermissions(@RequestBody @Valid ProductDTO productDTO, BindingResult br) throws Exception {
        LOG.warn("---------------- 开始处理待系列老公司权限 -------------------");
        long start = DateTimeUtil.getInt();
        // 成功数
        Integer successNum = 0;
        // 不更新公司数
        Integer notUpdateNum = 0;
        // 如果没传公司ID就取所有公司
        List<String> corpidList = CollectionUtils.isNotEmpty(productDTO.getCorpidList()) ? productDTO.getCorpidList() : companyModel.getCorpidList();
        int i = 1;
        //更新失败公司ID集合
        Set<String> errorCorpidList = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("del",0);
        param.put("columns","id, permissions");
        for (String corpid : corpidList) {
            int x = corpidList.size() - i;
            LOG.info("-----------------------------当前是第" + i + "家公司,还有" + x + "家是公司需要刷--------------------------");
            i++;
            try {
                //获取公司全部角色
                param.put("corpid",corpid);
                //自定义权限
                List<RoleEntity> roleEntityList = roleModel.findAllRoleByCorpid(param);
                //系统权限
                List<CoverRoleEntity> coverRoleEntityList = coverRoleModel.findEntitys(param);
                List<RoleEntity> updateRoleEntity = new ArrayList<>();
                roleEntityList.forEach(roleEnt -> {
                    String permissions = deleteRolePermissions(roleEnt.getPermissions());
                    if (!Objects.equals(permissions, roleEnt.getPermissions())){
                        RoleEntity roleEntity = new RoleEntity();
                        roleEntity.setId(roleEnt.getId());
                        roleEntity.setPermissions(permissions);
                        updateRoleEntity.add(roleEntity);
                    }
                });
                List<CoverRoleEntity> updateCoverRoleEntity = new ArrayList<>();
                coverRoleEntityList.forEach(coverRoleEnt -> {
                    String permissions = deleteRolePermissions(coverRoleEnt.getPermissions());
                    if (!Objects.equals(permissions, coverRoleEnt.getPermissions())){
                        CoverRoleEntity coverRoleEntity = new CoverRoleEntity();
                        coverRoleEntity.setId(coverRoleEnt.getId());
                        coverRoleEntity.setPermissions(permissions);
                        updateCoverRoleEntity.add(coverRoleEntity);
                    }
                });
                if (CollectionsUtil.isNotEmpty(updateRoleEntity)){
                    roleModel.updateBatchPermissions(updateRoleEntity, corpid);
                }
                if (CollectionsUtil.isNotEmpty(updateCoverRoleEntity)){
                    coverRoleModel.updateBatchPermissions(updateCoverRoleEntity, corpid);
                }
                if (updateRoleEntity.isEmpty() && updateCoverRoleEntity.isEmpty()){
                    notUpdateNum++;
                }else {
                    successNum++;
                }
            } catch (Exception e) {
                LOG.error("公司编号为:" + corpid + "更新失败,失败理由是", e);
                errorCorpidList.add(corpid);
            }
        }
        LOG.error("更新失败公司ID集合" + errorCorpidList.toString());
        LOG.warn("不更新公司数为:" + notUpdateNum);
        LOG.warn("consume:" + (DateTimeUtil.getInt() - start));
        LOG.warn("更新菜单表中数据操作成功,本次共更新了[{}]家公司数据", successNum);
        JSONObject object = new JSONObject();
        object.put("success", "成功");
        return object.toJSONString();
    }

    /**
     * 删除归档权限
     * @param permissions
     * @return
     */
    public String deleteRolePermissions(String permissions){
        StringBuilder stringBuilder = new StringBuilder();
        List<String> permissionsId = new ArrayList<>(Arrays.asList(permissions.split("\\|")));
        List<String> deleteId = new ArrayList<>();
        deleteId.add("1320");
        deleteId.add("1321");
        deleteId.add("1322");
        deleteId.add("1323");
        if (CollectionsUtil.isNotEmpty(permissionsId)){
            permissionsId.removeIf(item -> deleteId.contains(item));
            for (String perId : permissionsId){
                stringBuilder.append(perId).append("|");
            }
        }
        return stringBuilder.toString();
    }
}